home *** CD-ROM | disk | FTP | other *** search
/ QRZ! Ham Radio 1 / QRZ Ham Radio Callsign Database - December 1993.iso / ucsd / packet / tcpip / sys5 / iscwmpst.z / iscwmpst / tcp / src / icmphdr.c < prev    next >
Encoding:
C/C++ Source or Header  |  1991-02-25  |  2.2 KB  |  105 lines

  1. /* @(#) $Header: icmphdr.c,v 1.2 91/02/24 20:16:56 deyke Exp $ */
  2.  
  3. /* ICMP header conversion routines
  4.  * Copyright 1991 Phil Karn, KA9Q
  5.  */
  6. #include "global.h"
  7. #include "mbuf.h"
  8. #include "internet.h"
  9. #include "ip.h"
  10. #include "icmp.h"
  11.  
  12. /* Generate ICMP header in network byte order, link data, compute checksum */
  13. struct mbuf *
  14. htonicmp(icmp,data)
  15. struct icmp *icmp;
  16. struct mbuf *data;
  17. {
  18.     struct mbuf *bp;
  19.     register char *cp;
  20.     int16 checksum;
  21.  
  22.     if((bp = pushdown(data,ICMPLEN)) == NULLBUF)
  23.         return NULLBUF;
  24.     cp = bp->data;
  25.  
  26.     *cp++ = icmp->type;
  27.     *cp++ = icmp->code;
  28.     cp = put16(cp,0);               /* Clear checksum */
  29.     switch(icmp->type){
  30.     case ICMP_DEST_UNREACH:
  31.         if(icmp->code == ICMP_FRAG_NEEDED){
  32.             /* Deering/Mogul max MTU indication */
  33.             cp = put16(cp,0);
  34.             cp = put16(cp,icmp->args.mtu);
  35.         } else
  36.             cp = put32(cp,0L);
  37.         break;
  38.     case ICMP_PARAM_PROB:
  39.         *cp++ = icmp->args.pointer;
  40.         *cp++ = 0;
  41.         cp = put16(cp,0);
  42.         break;
  43.     case ICMP_REDIRECT:
  44.         cp = put32(cp,icmp->args.address);
  45.         break;
  46.     case ICMP_ECHO:
  47.     case ICMP_ECHO_REPLY:
  48.     case ICMP_TIMESTAMP:
  49.     case ICMP_TIME_REPLY:
  50.     case ICMP_INFO_RQST:
  51.     case ICMP_INFO_REPLY:
  52.         cp = put16(cp,icmp->args.echo.id);
  53.         cp = put16(cp,icmp->args.echo.seq);
  54.         break;
  55.     default:
  56.         cp = put32(cp,0L);
  57.         break;
  58.     }
  59.     /* Compute checksum, and stash result */
  60.     checksum = cksum(NULLHEADER,bp,len_p(bp));
  61.     cp = &bp->data[2];
  62.     cp = put16(cp,checksum);
  63.  
  64.     return bp;
  65. }
  66. /* Pull off ICMP header */
  67. int
  68. ntohicmp(icmp,bpp)
  69. struct icmp *icmp;
  70. struct mbuf **bpp;
  71. {
  72.     char icmpbuf[8];
  73.  
  74.     if(icmp == (struct icmp *)NULL)
  75.         return -1;
  76.     if(pullup(bpp,icmpbuf,8) != 8)
  77.         return -1;
  78.     icmp->type = icmpbuf[0];
  79.     icmp->code = icmpbuf[1];
  80.     switch(icmp->type){
  81.     case ICMP_DEST_UNREACH:
  82.         /* Retrieve Deering/Mogul MTU value */
  83.         if(icmp->code == ICMP_FRAG_NEEDED)
  84.             icmp->args.mtu = get16(&icmpbuf[6]);
  85.         break;
  86.     case ICMP_PARAM_PROB:
  87.         icmp->args.pointer = icmpbuf[4];
  88.         break;
  89.     case ICMP_REDIRECT:
  90.         icmp->args.address = get32(&icmpbuf[4]);
  91.         break;
  92.     case ICMP_ECHO:
  93.     case ICMP_ECHO_REPLY:
  94.     case ICMP_TIMESTAMP:
  95.     case ICMP_TIME_REPLY:
  96.     case ICMP_INFO_RQST:
  97.     case ICMP_INFO_REPLY:
  98.         icmp->args.echo.id = get16(&icmpbuf[4]);
  99.         icmp->args.echo.seq = get16(&icmpbuf[6]);
  100.         break;
  101.     }
  102.     return 0;
  103. }
  104.  
  105.